home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / internet / other / news / snz128s.tos / SRC / POST.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-28  |  25.0 KB  |  939 lines

  1. /*
  2.     SNEWS 2.0
  3.  
  4.     snews - posting stuff
  5.  
  6.  
  7.     Copyright (C) 1991    John McCombs, Christchurch, NEW ZEALAND
  8.                         john@ahuriri.gen.nz
  9.                         PO Box 2708, Christchurch, NEW ZEALAND
  10.  
  11.     This program is free software; you can redistribute it and/or modify
  12.     it under the terms of the GNU General Public License, version 1, as
  13.     published by the Free Software Foundation.
  14.  
  15.     This program is distributed in the hope that it will be useful,
  16.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.     GNU General Public License for more details.
  19.  
  20.     See the file COPYING, which contains a copy of the GNU General
  21.     Public License.
  22.  
  23.     Atari version ported by Graham Judd - gjudd@siward.demon.co.uk
  24.  
  25.  */
  26.  
  27. /*---------------------------- Source Control ------------------------------*/
  28.  
  29. /*
  30.  * $Id: post.c,v 1.3 1994/02/10 22:56:02 gbj Exp user $
  31.  */
  32.  
  33. /****************************************************************************
  34. *   20 May 92   1.2     GT  ka9q posting.                                   *
  35. *   22 May 92   1.3     GT  Make <dow> and <mth> public.                    *
  36. *   31 May 92   1.4     GT  Fix From:.                                      *
  37. *   03 Jun 92   1.5     GT  Less vigorous quoting.                          *
  38. *   08 Jun 92   1.6     GT  FQDN in "Path:".                                *
  39. *   09 Jun 92   1.7     GT  No local posting.                               *
  40. *   12 Jun 92   1.8     NJL Configurable quote marks; 50-line mode;         *
  41. *                           Ensure strtok() accepts tab as well as space.   *
  42. *   16 Jun 92   1.9     GT  Post via "mail2news".                           *
  43. *   20 Jul 92   1.10    GT  Close signature file.                           *
  44. *   26 Aug 92   1.11   MSM  Snews 1.90                                      *
  45. *   18 Oct 92   1.12   TOF  Allow empty entries of subj, dist, f-up         *
  46. *   21 Nov 92   1.13   MSM  Extra blank line in f0ollowup removed           *
  47. *   29 Dec 92   1.14   MSM  Prevent blank Organisation/Reply-to lines       *
  48. *   13 Feb 93   1.15   MSM  Re-enable local posting as an option            *
  49. *                           Change edit to edit whole message               *
  50. *   21 Mar 93   1.16   MSM  Allow "mail2news" to be configurable            *
  51. *    2 Jun 93   1.17   MSM  Snews 2.0                                       *
  52. *   28 Jun 93   1.18   MSM  Full edit on first pass                         *
  53. *    3 Oct 93   1.19   MSM  Extra abort options added                       *
  54. *                           Case sensitive y/n questions made insensitive   *
  55. *    4 Dec 93   1.20   MSM  Permit blank organisation                       *
  56. *   31 Jan 94   AT2    GBJ  Post news via nntp not smtp                     *
  57. *    2 Apr 94    1.21   GBJ  Followup to poster corrected to not post to     *
  58. *                newsgroup poster                    *
  59. *                Support footer quote for sigs            *
  60. ****************************************************************************/
  61.  
  62.  
  63.  
  64. #include "defs.h"
  65. #include "snews.h"
  66. #include "screen.h"
  67. #include "locking.h"
  68.  
  69. #ifdef ATARI
  70. #    include "fileops.h"
  71.     int pass_to_nntp(char *fname);
  72. #endif
  73.  
  74. #include <io.h>
  75. #include <time.h>
  76.  
  77. char           *dow[] = {
  78.     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  79. };
  80. char           *mth[] = {
  81.     "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
  82.     "Oct", "Nov", "Dec"
  83. };
  84.  
  85. /*
  86.  * The first type of marker is as used by View
  87.  * The second the more usual style of blank line
  88.  * Comment out as you wish
  89.  */
  90.  
  91. //char marker[] = "================================================================================\n";
  92. char marker[] = "\n";
  93.  
  94. extern long seqno;
  95.  
  96. /*------------------------------- post an article --------------------------*/
  97. int             post(TEXT * tx, char *gx, char *subject)
  98. {
  99.  
  100.     /*
  101.      * Ask for the data we are not given in the arguments, let him edit
  102.      * the article, then post it
  103.      */
  104.  
  105.     FILE           *article, *sig, *new_art;
  106.     LINES          *ln;
  107.     static char     buf[512], buf2[256], buf3[24];
  108.     static char     newsgroups[512];
  109.     static char     sig_fn[80];
  110.     static char     author[80], msg_id[80], r_name[128];
  111.     int             ch, lct, header;
  112.     static char     oldsubject[256];
  113.     static char     followupto[80];
  114.     int             rc, success = 0;
  115.     char        *ptr;
  116.  
  117.     strcpy(newsgroups, gx);
  118.     if (strlen(newsgroups) > 64) {
  119.         ptr = strchr(newsgroups, ',');
  120.         *ptr = '\0';
  121.     }
  122.     
  123.     strcpy(author, "");
  124.     strcpy(msg_id, "");
  125.     strcpy(followupto, "");
  126.  
  127.     if ((article = fopen("post.tmp", "w+")) != NULL) {
  128.  
  129.         command("");
  130.         lct = 1;
  131.         ch = 'y';
  132.         header = FALSE;
  133.         strcpy(oldsubject, "");
  134.         if (strlen(newsgroups) == 0) {
  135.  
  136.             /* if no groups ask for them */
  137.             lmessage("Newsgroups? ");
  138.             gets(newsgroups);
  139.  
  140.         }
  141.         else {
  142.  
  143.             /* there is a group ask if he wants to change */
  144.             if (tx != NULL) {
  145.                 sprintf(buf, "Followup is to %s, post to that group (y/n)?", newsgroups);
  146.             }
  147.             else {
  148.                 sprintf(buf, "Group: %s, post to *this* group (y/n)?", newsgroups);
  149.             }
  150.             message(buf);
  151.             do
  152.                 {
  153.                 ch = getch();
  154.                 ch = tolower(ch);
  155.             }
  156.             while ((ch != 'y') && (ch != 'n'));
  157.  
  158.             if (ch == 'n') {
  159.                 lmessage("Newsgroups? ");
  160.                 gets(newsgroups);
  161.             }
  162.         }
  163.  
  164.         /* check for a valid newsgroups line */
  165.         if (newsgroups_valid(newsgroups)) {
  166.             if (tx != NULL) {
  167.                 if (ch == 'y') {
  168.                     if (tx->follow_up == NULL)
  169.                         strcpy(newsgroups, tx->newsgroup);
  170.                     else {
  171.                         if (strnicmp(tx->follow_up, "poster", 6) == 0)
  172.                             strcpy(newsgroups, tx->newsgroup);
  173.                         else
  174.                             strcpy(newsgroups, tx->follow_up);
  175.                     }
  176.                 }
  177.                 if (newsgroups[strlen(newsgroups)-1] == '\n')
  178.                     newsgroups[strlen(newsgroups)-1] = '\0';
  179.                 message("Quote article (y/n/a)? ");
  180.                 do
  181.                     {
  182.                     ch = getch();
  183.                     ch = tolower(ch);
  184.                 }
  185.                 while ((ch != 'y') && (ch != 'n') && (ch != 'a'));
  186.                 textbackground(msgb);
  187.                 textcolor(msgf);
  188.                 putch(ch);
  189.                 putch('\n');
  190.                 putch('\r');
  191.                 textbackground(textb);
  192.                 textcolor(textf);
  193.             }
  194.             strcpy(oldsubject, subject);
  195.  
  196.             if (ch == 'a') {
  197.                 fclose(article);
  198.                 unlink("post.tmp");
  199.                 message("*** Article aborted - Press any key ***");
  200.                 getch();
  201.                 return -1;
  202.             }
  203.             if (strlen(subject) == 0) {      /* Subject does not exist */
  204.                 lmessage("Subject? ");
  205.                 gets(subject);
  206.             }
  207.  
  208.             if (my_stuff.expert == TRUE) {
  209.                 lct = post_header(tx, article, newsgroups, subject, msg_id,
  210.                                     lct);
  211.                 header = TRUE;
  212.             }
  213.  
  214.             /* add the quoted message */
  215.             /* are we quoting */
  216.             if (tx != NULL) {
  217.  
  218.                 get_his_stuff(tx, author, msg_id, r_name);
  219.  
  220.                 if (ch == 'y') {
  221.  
  222.                     strcpy(buf2, " ");
  223.                     strcpy(buf3, " ");
  224.                     if ((strlen(msg_id) + strlen(author) + strlen(r_name)) > 60) {
  225.                         strcpy(buf2, "\n           ");
  226.                         if ((strlen(author) + strlen(r_name)) > 60)
  227.                             strcpy(buf3, "\n           ");
  228.                     }
  229.                     fprintf(article, "In article %s%s%s%s%s writes:\n\n", msg_id, buf2, author, buf3, r_name);
  230.                     if (my_stuff.header_quote)
  231.                         ln = tx->top;
  232.                     else
  233.                         ln = tx->start;
  234.                     while (ln != NULL) {
  235.                         if ((strncmp(ln->data, "-- ", 3) == 0) && my_stuff.footer_quote)
  236.                             break;
  237.                         fprintf(article, "%s%s", my_stuff.quotemark, ln->data);
  238.                         ln = ln->next;
  239.                     }
  240.                 }
  241.             }
  242.  
  243.             /* append the signature if there is one */
  244.             strcpy(sig_fn, my_stuff.home);
  245.             strcat(sig_fn, my_stuff.signature);
  246.             if ((sig = fopen(sig_fn, "rt")) != NULL) {
  247.                 if (my_stuff.footer_quote)
  248.                     fprintf(article, "\n-- \n");
  249.                 else
  250.                     fprintf(article, "\n");
  251.                 while (fgets(buf, 79, sig) != NULL)
  252.                     fputs(buf, article);
  253.  
  254.                 (void) fclose(sig);
  255.             }
  256.  
  257.  
  258.             fclose(article);
  259.             ch = 'e';
  260.             while ((ch != 'p') && (ch != 'a')) {
  261.                 if (ch == 'e') {
  262.                     sprintf(buf, my_stuff.editor, "post.tmp");
  263.                     strcpy(buf2, buf);
  264.                     if (my_stuff.edit_line != NULL) {
  265.                         strcat(buf2, " ");
  266.                         if (header == TRUE)
  267.                             sprintf(buf, my_stuff.edit_line, lct+1);
  268.                         else
  269.                             sprintf(buf, my_stuff.edit_line, lct);
  270.                         strcat(buf2, buf);
  271.                         }
  272.                     rc = system(buf2);
  273.                     if (rc != 0) {
  274.                         success = 0;
  275.                         unlink("post.tmp");
  276.                         if (strlen(oldsubject) > 0)
  277.                             strcpy(subject, oldsubject);
  278.                         return success;
  279.                     }
  280.                 }
  281.  
  282.                 if ((my_stuff.expert != TRUE) && (header == FALSE)) {
  283.                     if ((article = fopen("post.tmp", "r")) == NULL) {
  284.                         success = 0;
  285.                         unlink("post.tmp");
  286.                         if (strlen(oldsubject) > 0)
  287.                             strcpy(subject, oldsubject);
  288.                         return success;
  289.                     }
  290.                     if ((new_art = fopen("new.tmp", "w+")) == NULL) {
  291.                         success = 0;
  292.                         unlink("post.tmp");
  293.                         if (strlen(oldsubject) > 0)
  294.                             strcpy(subject, oldsubject);
  295.                         return success;
  296.                     }
  297.                     lct = post_header(tx, new_art, newsgroups, subject,
  298.                                         msg_id, lct);
  299.                     while (fgets(buf, sizeof(buf), article) != NULL) {
  300.                         fputs(buf, new_art);
  301.                     }
  302.                     fclose(article);
  303.                     fclose(new_art);
  304.                     unlink("post.tmp");
  305.                     rename("new.tmp", "post.tmp");
  306.                     header = TRUE;
  307.                 }
  308.  
  309.                 gotoxy(1, scr_rows - 2);
  310.                 textbackground(msgb);
  311.                 textcolor(msgf);
  312.                 clreol();
  313.                 cprintf("Post Article to newsgroups ?");
  314.                 textbackground(textb);
  315.                 textcolor(textf);
  316.                 gotoxy(1, scr_rows - 1);
  317.                 sprintf(buf, "(P)ost, (E)dit or (A)bort ? (p/e/a):");
  318.                 message(buf);
  319.                 while (((ch = getch()) != 'p') && (ch != 'a') && (ch != 'e'));
  320.                 gotoxy(1, 24);
  321.             }
  322.             gotoxy(1, scr_rows - 2);
  323.             textbackground(msgb);
  324.             textcolor(msgf);
  325.             clreol();
  326.  
  327.             if (ch == 'p') {
  328.                   success = post_it("post.tmp", newsgroups);
  329.                 message("*** Article posted - Press any key ***");
  330.                 getch();
  331.             }
  332.             if (ch == 'a') {
  333.                 message("*** Article aborted - Press any key ***");
  334.                 getch();
  335.             }
  336.  
  337.         }
  338.  
  339.         fclose(article);
  340.         unlink("post.tmp");
  341.         if (strlen(oldsubject) > 0)
  342.             strcpy(subject, oldsubject);
  343.  
  344.     }
  345.     else {
  346.         message("*** couldn't open temp article file - press any key ***");
  347.         getch();
  348.         success = 0;
  349.     }
  350.  
  351.     return success;
  352. }
  353. /*----------------------- Add Article Header ------------------------------*/
  354. int             post_header(TEXT *tx, FILE *article, char *newsgroups,
  355.                             char *subject, char *msg_id, int lct)
  356. {
  357.     struct tm      *gmt;
  358.     time_t          t;
  359.     char           *p;
  360.     static char     distribution[80];
  361.     char            buf[256];
  362.     char            author[80], r_name[128];
  363.  
  364.     if ((tx != NULL) && (tx->distribution != NULL))
  365.         strcpy(distribution, tx->distribution);
  366.     else
  367.         strcpy(distribution, "");
  368.     
  369.     if (strlen(distribution) > 0)
  370.         if (distribution[strlen(distribution)-1] == '\n')
  371.             distribution[strlen(distribution)-1] = '\0';
  372.     
  373.     fprintf(article, "Path: %s.%s!%s\n", my_stuff.my_site,
  374.                   my_stuff.my_domain, my_stuff.user);
  375.     lct++;
  376.     fprintf(article, "From: %s@%s.%s (%s)\n", my_stuff.user,
  377.               my_stuff.my_site, my_stuff.my_domain, my_stuff.my_name);
  378.     lct++;
  379. #ifndef ATARI
  380.     fprintf(article, "To: %s@%s\n", my_stuff.mail_id, my_stuff.mail_server);
  381.     lct++;
  382.     fprintf(article, "Cc: \n");
  383.     lct++;
  384.     fprintf(article, "Bcc: \n");
  385.     lct++;
  386. #endif
  387.     fprintf(article, "Newsgroups: ");
  388.     strcpy(buf, newsgroups);
  389.     p = strtok(buf, " \t,");
  390.     if (p != NULL) {
  391.         fprintf(article, "%s", p);
  392.         p = strtok(NULL, " \t,");
  393.     }
  394.     while (p != NULL) {
  395.         fprintf(article, ",\n %s", p);
  396.         lct++;
  397.         p = strtok(NULL, " \t,");
  398.     }
  399.     fprintf(article, "\n");
  400.     lct++;
  401.     if (tx != NULL)
  402.         get_his_stuff(tx, author, msg_id, r_name);
  403.     if ((strlen(msg_id) > 0) && strnicmp(subject, "re: ", 4) != 0)
  404.         fprintf(article, "Subject: Re: %s\n", subject);
  405.     else
  406.         fprintf(article, "Subject: %s\n", subject);
  407.     lct++;
  408.  
  409.     if (strlen(distribution) > 0)
  410.         if (distribution[0] != ' ') {
  411.             fprintf(article, "Distribution: %s\n", distribution);
  412.             lct++;
  413.         }
  414. #ifdef ATARI
  415.         time(&t);
  416.         gmt=gmtime(&t);
  417.         sprintf(buf,
  418.         "Message-ID: <%02d%02d%02dZ%02d%02d%02d.%03d%s@%s.%s>",
  419.         gmt->tm_year % 100, gmt->tm_mon+1, gmt->tm_mday,
  420.         gmt->tm_hour, gmt->tm_min, gmt->tm_sec, clock() % 1000,
  421.         my_stuff.user, my_stuff.my_site, my_stuff.my_domain);
  422. #else
  423.     sprintf(buf, "Message-ID: <%ldsnz@%s.%s>",
  424.         time(&t), my_stuff.my_site, my_stuff.my_domain);
  425. #endif
  426.     fprintf(article, "%s\n", buf);
  427.     lct++;
  428.  
  429.     if (strlen(msg_id) > 0) {
  430.         if ((tx != NULL) && (tx->references != NULL) && (strlen(tx->references) < 240)) {
  431.             strcpy(buf, tx->references);
  432.             if (buf[strlen(buf)-1] == '\n')
  433.                 buf[strlen(buf)-1] = '\0';
  434.             fprintf(article, "References: %s %s\n", buf, msg_id);
  435.         }
  436.         else
  437.             fprintf(article, "References: %s\n", msg_id);
  438.         lct++;
  439.     }
  440. #ifndef ATARI
  441.     time(&t);
  442.     gmt=gmtime(&t);
  443. #endif
  444.     fprintf(article, "Date: %s, %02d %s %02d %02d:%02d:%02d GMT\n",
  445.         dow[gmt->tm_wday],
  446.         gmt->tm_mday, mth[gmt->tm_mon], (gmt->tm_year % 100),
  447.         gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
  448.     lct++;
  449.  
  450. #ifdef ATARI
  451.     if (my_stuff.my_organisation != NULL)
  452.         if (strlen(my_stuff.my_organisation) > 0)
  453.             fprintf(article, "Organization: %s\n", my_stuff.my_organisation);
  454.         else
  455.             fprintf(article, "Organization: \n");
  456.     else
  457.             fprintf(article, "Organization: \n");
  458. #else
  459.     if ((my_stuff.my_organisation != NULL) && (strlen(my_stuff.my_organisation) > 0))
  460.         fprintf(article, "Organization: %s\n", my_stuff.my_organisation);
  461.     else
  462.         fprintf(article, "Organization: \n");
  463. #endif
  464.     lct++;
  465.  
  466.     if (my_stuff.replyuser != '\0') {
  467.         fprintf(article, "Reply-To: %s\n", my_stuff.replyuser);
  468.         lct++;
  469.     }
  470.  
  471.     fprintf(article, "Followup-To: \n");
  472.     lct++;
  473.  
  474.     fprintf(article, "X-Newsreader: %s\n", VERSION);
  475.     lct++;
  476.  
  477.     fprintf(article, "%s", marker);
  478.  
  479.     return lct;
  480. }
  481.  
  482. /*--------------------------- post an article ---------------------------*/
  483. int             post_it(char *artfile, char *newsgroups)
  484. {
  485.  
  486.     /*
  487.      * Post an article.  The article is passed as a closed file, a
  488.      * line count is added and the article sent. The article file is
  489.      * however open on return, to be close by post and deleted if no
  490.      * longer required.
  491.      *
  492.      * Note that the newsgroups and subject passed are those given
  493.      * before the article was edited and may have been changed.
  494.      *
  495.      * The Atari port creates article files suitable for direct posting
  496.      * via nntp rather than mailing mail files.
  497.      */
  498.  
  499.     FILE           *article, *tmp, *local;
  500.     FILE           *seq_fp;
  501.     static char     buf[256], buf2[256];
  502.     char           *p, msgid[80];
  503.     static char     ng[512], subject[128];
  504.     static char     short_d_name[20];
  505.     int             ct, in_header;
  506.     int             junk_flag;
  507.     long            where;
  508.     time_t          t;
  509.     ACTIVE         *gp;
  510.     int             success = 0;
  511.     int             m;
  512.     char           *new_read;
  513. #ifndef ATARI
  514.     WRK_FILE      *wrk;
  515. #endif
  516.  
  517.     ct = 0;
  518.     time(&t);
  519.  
  520.     strcpy(buf, my_stuff.spooldir);
  521.     strcat(buf, "sequence.seq");
  522.     if (mlock(my_stuff.spooldir, "sequence", "Snews") != 0) {
  523.         message("*** Couldn't lock sequence file - press any key ***");
  524.         getch();
  525.         return 0;
  526.     }
  527.     if ((seq_fp = fopen(buf, "r+")) == NULL) {
  528.         message("*** Coundn't open mail sequence file - press any key ***");
  529.         getch();
  530.         return 0;
  531.     }
  532.     /* Get the next sequence number */
  533.     rewind(seq_fp);
  534.     fscanf(seq_fp, "%ld", &seqno);
  535.     seqno++;
  536.     rewind(seq_fp);
  537.     fprintf(seq_fp, "%ld\n", seqno);
  538.     fclose(seq_fp);
  539.     rmlock(my_stuff.spooldir, "sequence", "Snews");
  540.  
  541. #ifndef ATARI
  542.     if ((wrk = parse(artfile, FALSE)) == NULL)
  543.         return 0;
  544.  
  545.     pass_to_smtp(artfile, wrk, FALSE);
  546. #else
  547.     if (!pass_to_nntp(artfile))
  548.         return 0;
  549. #endif
  550.  
  551.     if ((article = fopen(artfile ,"rt")) == NULL) {
  552.         message("*** couldn't open temp article file - press any key ***");
  553.         getch();
  554.         return 0;
  555.     }
  556.     
  557.     if (my_stuff.localpost == 1) {
  558.         /* ok, now post it locally */
  559.         /* count the lines */
  560.         rewind(article);
  561.         ct = 0;
  562.         in_header = TRUE;
  563.         while (fgets(buf, 255, article) != NULL) {
  564.             if ((strncmp(buf, marker, 80) == 0) && (in_header == TRUE)) {
  565.                 in_header = FALSE;
  566.             }
  567.             if (in_header == FALSE)
  568.                 ct++;
  569.         }
  570.         ct--;
  571.  
  572.         sprintf(short_d_name, "D.%.3s", my_stuff.my_site);
  573.         if ((tmp = fopen(short_d_name, "w+/*b*/")) != NULL) {
  574.  
  575.             /* copy the rest */
  576.             rewind(article);
  577.             in_header = TRUE;
  578.             while (fgets(buf, 255, article) != NULL) {
  579.                 where = ftell(article);
  580.                 if ((in_header == TRUE) && (strncmp(buf, marker, 80) == 0)) {
  581.                     sprintf(buf, "Lines: %d\n\n", ct);
  582.                     in_header = FALSE;
  583.                 }
  584.                 if ((strnicmp(buf, "BC:", 3) == 0) && (in_header == TRUE))
  585.                       continue;
  586.                 if ((strnicmp(buf, "BCC:", 4) == 0) && (in_header == TRUE))
  587.                     continue;
  588.                 if ((strnicmp(buf, "Subject:", 8) == 0) && (in_header == TRUE)) {
  589.                     strcpy(subject, buf+9);
  590.                     if (subject[strlen(subject)-1] != '\0')
  591.                         subject[strlen(subject)-1] = '\0';
  592.                 }
  593.                 if ((strnicmp(buf, "Message-ID:", 11) == 0) && (in_header == TRUE)) {
  594.                     strcpy(msgid, buf+12);
  595.                     if (msgid[strlen(msgid)-1] == '\n')
  596.                         msgid[strlen(msgid)-1] = '\0';
  597.                 }
  598.                 if ((strnicmp(buf, "Newsgroups:", 11) == 0) && (in_header == TRUE)) {
  599.                     strcpy(ng, buf+12);
  600.                     if (ng[strlen(ng)-1] == '\n')
  601.                         ng[strlen(ng)-1] = '\0';
  602.                     do
  603.                         {
  604.                         if (fgets(buf2, 255, article) != NULL) {
  605.                             if (buf2[0] == ' ') {
  606.                                 strcat(ng, buf2);
  607.                                 if (ng[strlen(ng)-1] == '\n')
  608.                                     ng[strlen(ng)-1] = '\0';
  609.                             }
  610.                         }
  611.                         else
  612.                             buf2[0] = '\0';
  613.                     }
  614.                     while (buf2[0] == ' ');
  615.                 }
  616.                 if ((in_header == TRUE) && (buf[0] != ' ')) {
  617.                     strcpy(buf2, buf);
  618.                     p = strtok(buf2, ":");
  619.                     p = strtok(NULL, " \t");
  620.                     if (p != NULL)
  621.                         if (strcmp(p, "\n") == 0)
  622.                             continue;
  623.                 }
  624.                     fputs(buf, tmp);
  625.                 fseek(article, where, SEEK_SET);
  626.             }
  627.  
  628.             p = strtok(ng, " ,\t");
  629.             while (p != NULL) {
  630.  
  631.                 rewind(tmp);
  632.  
  633.                 local = open_out_file(p, &junk_flag);
  634.                 where = ftell(local);
  635.                 while (fgets(buf, 255, tmp) != NULL) {
  636.                     fputs(buf, local);
  637.                 }
  638.                 fprintf(local, "\n@@@@END\n");
  639.                 fclose(local);
  640.                 gp = find_news_group(p, &junk_flag);
  641.  
  642.                 /* update the read list */
  643.                 ct = (int) (gp->hi_num - gp->lo_num);
  644.                 new_read = (char *) malloc(ct * sizeof(int));
  645.                 for (m=0;m<ct-1;m++) {
  646.                     *(new_read + m) = *(gp->read_list + m);
  647.                 }
  648.                 if (my_stuff.localread != 1)
  649.                     *(new_read + ct - 1) = FALSE;
  650.                 else
  651.                     *(new_read + ct - 1) = TRUE;
  652.                 free(gp->read_list);
  653.                 gp->read_list = new_read;
  654.  
  655.                 /* save the data in the index file */
  656.                 local = open_index_file(p);
  657.                 fprintf(local, "%08ld %08ld %09ld  %s\n", where, gp->hi_num, t,
  658.                         subject);
  659.                 fclose(local);
  660.  
  661.                 p = strtok(NULL, " ,\t");
  662.  
  663.             }
  664.             /* now update the snews history */
  665.             open_hist_file();
  666.             add_hist_record(msgid, newsgroups);
  667.             close_hist_file();
  668.  
  669.             /* now don't forget nntp history */
  670.             sprintf(buf, "%shistory.lck", my_stuff.nntp_dir);
  671.             if ((local = fopen(buf, "rt")) != NULL) {
  672.                 fclose(local);  /* Lock present - can't update */
  673.             }
  674.             else {
  675.                 sprintf(buf, "%shistory", my_stuff.nntp_dir);
  676.                 local = fopen(buf, "at");
  677.                 fputs(msgid, local);
  678.                 fputs("\n", local);
  679.                 fclose(local);
  680.             }
  681.             /* Yes I know I am ignoring errors here ! it seems appropriate */
  682.         }
  683.         else {
  684.             message("*** couldn't open temp post file - press any key ***");
  685.             getch();
  686.             success = 0;
  687.             return success;
  688.         }
  689.         fclose(tmp);
  690.         unlink(short_d_name);
  691.     }
  692.     success = 1;
  693.     return success;
  694. }
  695.  
  696.  
  697.  
  698. /*------------------------ parse and check newsgroups ---------------------*/
  699. int             newsgroups_valid(char *ng)
  700. {
  701.  
  702.     /*
  703.      * This routine parses the newsgroup list, and checks them for validity
  704.      */
  705.  
  706.     static char     buf[256], msg[128];
  707.     char           *p;
  708.  
  709.     strcpy(buf, ng);
  710.  
  711.     if ((p = strtok(buf, ", \t")) == NULL)
  712.         return (FALSE);
  713.  
  714.     while (p != NULL) {
  715.         if (!check_valid_post_group(p)) {
  716.             sprintf(msg, "** Can't post to %s **", p);
  717.             message(msg);
  718.             command("-- Press any key to continue --");
  719.             getch();
  720.             return (FALSE);
  721.         }
  722.         p = strtok(NULL, ", \t");
  723.     }
  724.  
  725.     return (TRUE);
  726. }
  727.  
  728. #ifdef ATARI
  729.  
  730. /****************************************************************************
  731.     Parse NNTP message and queue for transmission - ATARI only
  732. *****************************************************************************/
  733. /*
  734.  *    NOTE: 940210 GBJ Changed success return to 1 and error return to 0.
  735.  */
  736. int    pass_to_nntp(char *fname)
  737. {
  738.     int        isfrom, isnewsgps, isid, need_edit;
  739.     int        isnottoken, in_header, ch, line_ct;
  740.     char        *p;
  741.     char        buff[512];
  742.     char        nwgrp[512], msgid[512];
  743.     FILE        *fp, *logfp, *txtfp, *wrkfp;
  744.     time_t        t;
  745.     struct tm    *gmt;
  746.     
  747.     
  748.     isfrom = isnewsgps = isid = need_edit = FALSE;
  749.  
  750.     if ((fp = fopen(fname, "rt")) == NULL) {
  751.         message("*** Cannot open news file - press any key to continue ***");
  752.         getch();
  753.         return 0;    /* give up */
  754.     }
  755.  
  756. /*
  757.     Check that all the required headers are in place - run editor and
  758.     re-scan the headers if not
  759. */
  760.  
  761.     do    {
  762.         need_edit = FALSE;
  763.         in_header = TRUE;
  764.         isnottoken = FALSE;
  765.  
  766.         while (fgets(buff, 511, fp) != NULL) {
  767.             if (strncmp(buff, marker, 80) == 0) {
  768.                 in_header = FALSE;
  769.                 break;
  770.             }
  771.             if (in_header == TRUE) {
  772.                 if ((strnicmp(buff, "FROM:", 5) == 0) && (strlen(buff) > 8))
  773.                     isfrom = TRUE;
  774.  
  775.                 if ((strnicmp(buff, "MESSAGE-ID:", 11) == 0) && (strlen(buff) > 14)) {
  776.                     isid  = TRUE;
  777.                     strncpy(msgid, buff + 12, strlen(buff) - 11);
  778.                 }
  779.                 if ((strnicmp(buff, "NEWSGROUPS:", 11) == 0) && (strlen(buff) > 14)) {
  780.                     isnewsgps = TRUE;
  781.                     strncpy(nwgrp, buff + 12, strlen(buff) - 11);
  782.                 }
  783.  
  784.                 if ((strchr(buff, ':') == NULL) && (buff[0] != ' '))
  785.                     isnottoken = TRUE;
  786.             }
  787.         }
  788.  
  789.         if (in_header == TRUE) {
  790.             message("*** End of header not found - press any key ***");
  791.             getch();
  792.             need_edit = TRUE;
  793.         }
  794.         
  795.         if (isnottoken == TRUE) {
  796.             message("*** Invalid header line found - press any key ***");
  797.             getch();
  798.             need_edit = TRUE;
  799.         }
  800.  
  801.         if (isfrom == FALSE) {
  802.             message("*** No 'From:' line in header - press any key ***");
  803.             getch();
  804.             need_edit = TRUE;
  805.         }
  806.         
  807.         if (isid == FALSE) {
  808.             message("*** No 'Message-ID:' line in header - press any key ***");
  809.             getch();
  810.             need_edit = TRUE;
  811.         }
  812.         if (isnewsgps == FALSE) {
  813.             message("*** No 'Newsgroups:' line in header - press any key ***");
  814.             getch();
  815.             need_edit = TRUE;
  816.         }
  817.  
  818.         if (need_edit == TRUE) {
  819.             fclose(fp);
  820.             message("(E)dit or (A)bort (e/a) ? ");
  821.  
  822.             do    {
  823.                 ch = getch();
  824.                 ch = tolower(ch);
  825.             } while((ch != 'e') && (ch != 'a'));
  826.  
  827.             if (ch == 'a')
  828.                 return 0;                            /* no edit so abort    */
  829.  
  830.             sprintf(buff, my_stuff.editor, fname);
  831.             system(buff);
  832.  
  833.             if ((fp = fopen(fname, "rt")) == NULL) {
  834.                 message("*** Unable to open news file - press any key ***");
  835.                 getch();
  836.                 return 0;
  837.             }
  838.         }
  839.     } while(need_edit == TRUE);                /* loop until all headers found    */
  840.  
  841. /* Count the lines in the body of the article */
  842.  
  843.     rewind(fp);
  844.     in_header = TRUE;
  845.     while (fgets(buff, sizeof(buff), fp) != NULL) {
  846.         if ((strncmp(buff, marker, 80) == 0) && (in_header == TRUE)) {
  847.             in_header = FALSE;
  848.             line_ct = 0;
  849.         }
  850.         if (in_header == FALSE)
  851.             line_ct++;
  852.     }
  853.     line_ct--;
  854.  
  855. /* look for and open the local log file */
  856.  
  857.     logfp = NULL;
  858.  
  859.     if (stricmp(my_stuff.mailuser, "none") != 0) {
  860.         sprintf(buff, "%s%s.txt", my_stuff.mail_dir, my_stuff.mailuser);
  861.         if ((logfp = fopen(buff, "at")) == NULL) {
  862.             message("*** unable to open post log file - press any key ***");
  863.             getch();  /* this is not a fatal error */
  864.         }
  865.         
  866.         time(&t);
  867.         gmt = gmtime(&t);
  868.         fprintf(logfp, "From %s@%s.%s ", my_stuff.user, my_stuff.my_site,
  869.         my_stuff.my_domain);
  870.         fprintf(logfp, "%s, %02d %s %02d %02d:%02d:%02d GMT\n",
  871.             dow[gmt->tm_wday],
  872.             gmt->tm_mday, mth[gmt->tm_mon], (gmt->tm_year % 100),
  873.             gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
  874.     }
  875.  
  876. /* create the nntp text file with a .txt suffix    */
  877.  
  878.     sprintf(buff, "%s\\%ld.txt", my_stuff.spooldir, seqno);
  879.     if ((txtfp = fopen(buff, "w")) == NULL) {
  880.         message("*** unable to create nntp text file - press any key ***");
  881.         getch();
  882.         if (logfp != NULL)
  883.             fclose(logfp);
  884.         return 0;
  885.     }
  886.     
  887.     rewind(fp);
  888.     in_header = TRUE;
  889.  
  890.     while (fgets(buff, sizeof(buff), fp) != NULL) {
  891.         if (in_header) {
  892.             if (strncmp(buff, "Followup-To: \n", 14) == 0) {
  893.                 continue;    /* Don't write a blank line */
  894.             }
  895.             if (strncmp(buff, marker, 80) == 0) {
  896.                 sprintf(buff, "Lines: %d\n\n", line_ct);
  897.                 in_header = FALSE;
  898.             }
  899.         }
  900.  
  901.         fputs(buff, txtfp);    /* copy line to article file */
  902.  
  903.         if (logfp != NULL)
  904.             fputs(buff, logfp);    /* copy line to log file */
  905.     }
  906.  
  907.     fclose(fp);        /* close the temp article file    */
  908.     fclose(txtfp);        /* close the nntp article file    */
  909.  
  910.     if (logfp != NULL)
  911.         fclose(logfp);    /* close log file */
  912.  
  913. /*    create the nntp work file with a .nwk suffix */
  914.  
  915.     sprintf(buff, "%s\\%ld.nwk", my_stuff.spooldir, seqno);
  916.  
  917.     if ((wrkfp = fopen(buff, "w")) == NULL) {
  918.         message("*** unable to create nntp work file - press any key ***");
  919.         getch();
  920.         return 0;
  921.     }
  922.     
  923.     fprintf(wrkfp, "%s", msgid);    /* print msgid in work file */
  924.  
  925.     for (p = nwgrp; *p; p++) {    /* scan for ',' and translate */
  926.         if (*p == ',')        /*    into '\n' */
  927.             *p = '\n';
  928.     }
  929.  
  930.     fprintf(wrkfp, "%s\n", nwgrp);    /* print news groups 1 per line    */
  931.     
  932.     fclose(wrkfp);            /* close the work file    */
  933.  
  934.     return 1;            /* return, all OK */
  935. }
  936.  
  937. #endif
  938.           
  939.